# 文件 I/O
# 文件打开，open(...) 内建函数
file_name = 'hello_module.py'
# 打开文件， open读取分为二进制和纯文本读取，默认是以文本文件打开的
fd = open(file_name)
print(fd, type(fd))
# help(fd) # 查看类的帮助
print(fd.read()) # 读取文件
# 关闭文件
fd.close()
# 中文
file_name = 'README.md'
fd = open(file_name, encoding='UTF-8') # 指定unicode编码，读取中文
print(fd.read(10), end='') # 读取10个字符
print(fd.read(20)) # 读取20个字符，每次读取会从上次读取位置继续读取, 大文件需要分块读取
fd.close()

# python的流关闭语句 类似于java try(..)
# with closeable对象 as 变量:
#       pass
with open(file_name, encoding = 'UTF-8') as f:
    print(f.readline()) # 读取一行
    print(f.readlines(3)) # 读取多行，存储在list列表中，一行一个


with open('hello_module.py') as f:
    # 每次循环会读取一行，file对象实现了iterator
    for line in f:
        print(line)

# 写入 wt会删除原文件内容(等同于w) at追加(等同于a) 文件不存在都会创建文件 t文本模式(默认)，b二进制模式
# r+ 可读可写，但是不存在不创建
# w+ 可读可写，重写，不存在创建
# a+ 可读可写，追加，不存在创建
# x 不存在并创建写入，存在则不创建报错
file_name = 'demo.txt'
with open(file_name, mode='wt', encoding='UTF-8') as f:
    f.write('python demo')

# seek 找到指定位置 tell 查看读取位置
with open(file_name, mode='rb') as f:
    print(f.read(5))
    print('read pos ->', f.tell()) # 当前读取到的位置
    print(f.seek(2), f.read(1)) # 跳到第二个字节位置开始读取，如果是t模式，则是字符数，b模式是字节数
    print('read pos ->', f.tell()) # 当前读取到的位置
    # 默认seek是从头开始计算位置，
    # 如果想每次都从上一次计算的位置开始计算则传递第二个参数
    #   0 代表从头开始
    #   1 代表从当前位置计算，默认0
    #   2 从后往前
    f.seek(1, 1) # 只支持b模式，二进制
    f.seek(1, 1) 
    f.seek(-1, 2) # 从最后开始计算，倒数第一个位置
    print('read pos ->', f.tell(), f.read(1)) # 当前读取到的位置

# 系统交互操作的基本命令都可以
import os
# 重命名
# print(os.rename(file_name, 'demo1'))
# 删除文件
os.remove(file_name)
import pprint as p
# list文件
p.pprint(os.listdir())
p.pprint(os.getcwd())

# 除了上面文件操作，还提供了StringIO和ByteIO类似于文件操作的方式再内存中进行
from io import StringIO
from io import BytesIO
fo = StringIO()
fo.write('hello')
fo.write('world!')
print(fo.getvalue())

fo = BytesIO()
fo.write('中文'.encode('utf-8'))
print(fo.getvalue())
